﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OracleClient;
using System.Data.Linq.Mapping;
using System.Data.Linq;
using System.Data.SqlClient;
using System.Reflection;
using System.IO;

namespace InfoWykaz
{
    /*
     *      Klasa do połączenia się z db oracla.
     */
    public class OraCon
    {
        //utworzenie connection string
        public static string GetConnectionString()
        {
            FileInfo f = new FileInfo("config.xml");
            OptionsValue options=null;
            string res = string.Empty;
            if (f.Exists)
            {
                options = Serialize.DeserializeFromXml(f);
                res = string.Format("Data Source={0};Persist Security Info=True;" +
                       "User ID={1};Password={2};Unicode=True",
                       options.dataBase,
                       options.user,
                       options.password);
            }
            else res = string.Format("Data Source=szpital;Persist Security Info=True;" +
                       "User ID=sysadm;Password=sysadm;Unicode=True");
            return res;
        }

        //metoda wysyłająca zapytania i zwracająca wynik w postaci DataTable.
        public static DataTable ConnectAndQuery(string query)
        {
            try
            {
                using (OracleConnection connection = new OracleConnection())
                {
                    connection.ConnectionString = GetConnectionString();
                    connection.Open();
                    //OracleCommand command = connection.CreateCommand();
                    //command.CommandText = query;
                    OracleDataAdapter adapter = new OracleDataAdapter(query, connection);
                    DataTable oDt = new DataTable("Dane");
                    adapter.Fill(oDt);
                    return oDt;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return null;
            }
        }

        //metoda zwracająca linq jako datatable
        public static DataTable LINQToDataTable<T>(IEnumerable<T> varlist)
        {
            DataTable dtReturn = new DataTable();

            // nazwy kolumn
            PropertyInfo[] oProps = null;

            if (varlist == null) return dtReturn;


            //jesli nie informacji o kolumnach to 
            if (oProps == null)
            {
                //pobranie informacji na temat typu zmiennej
                oProps = ((Type)varlist.ElementAt(0).GetType()).GetProperties();
                foreach (PropertyInfo pi in oProps)
                {
                    Type colType = pi.PropertyType;

                    if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition()
                    == typeof(Nullable<>)))
                    {
                        //pobranie typu kolumny
                        colType = colType.GetGenericArguments()[0];
                    }
                    //dodanie nowej kolumny o odpowiednim typie oraz nazwie
                    dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
                }
            }

            //przejscie po kazdym wierszu zapytania
            foreach (T rec in varlist)
            {
                //utworzenie nowego wiersza z zwracanej tabeli
                DataRow dr = dtReturn.NewRow();

                foreach (PropertyInfo pi in oProps)
                {
                    //przypisanie wartości z wiersza w zapytaniu do nowego wiersza
                    dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue
                    (rec, null);
                }

                //dodanie nowego wiersza do zwracanej tabeli
                dtReturn.Rows.Add(dr);
            }
            return dtReturn;
        }

        //metoda zwracająca date w formacie oracla z datetie
        public static string getDate(DateTime dt)
        {
            return string.Format("{0}-{1}-{2} 00:00",
                dt.Year,
                fitIntByString(dt.Month, "0", 2, 1),
                fitIntByString(dt.Day, "0", 2, 1));
        }

        //metoda uzupełnia stringa o zadanego stringa
        private static string fitIntByString(int x, string s, int les, int count)
        {
            string result = x.ToString();
            if (x.ToString().Length < les)
                for (int i = 0; i < count; i++) result = string.Format("{0}{1}", s, result);
            return result;
        }
    }
}
